﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SegIdenMovil.Entidad;
using GS1.Library;
using SegIdenMovil.Herramientas;
using SegIdenMovil.Delegate;

namespace SegIdenMovil
{
    public partial class frmVentaDetalle : Form
    {
        #region --- Variables y Constantes ---
        public Venta venta { get; set; }

        private string codigoBarraActual = string.Empty;

        private ListaItem listaItem = null;

        private Item itemActual = null;

        private Double igvActual = 0.18;

        private Boolean bCalcDscto = false;

        private ListaLineaVenta listaLineaVenta = null;
        #endregion

        #region --- Constructor ---
        public frmVentaDetalle()
        {
            InitializeComponent();
        }
        #endregion

        #region --- Eventos Formulario ---
        private void frmVentaDetalle_Load(object sender, EventArgs e)
        {
            cargarFormulario();
        }

        private void frmVentaDetalle_Closing(object sender, CancelEventArgs e)
        {
            activarScanner(false);
        }

        private void btnImagen_Click(object sender, EventArgs e)
        {
            verImagen();
        }

        private void mnuConfirmar_Click(object sender, EventArgs e)
        {
            guardar();
        }

        private void mnuSalir_Click(object sender, EventArgs e)
        {
            salir();
        }

        private void btnEliminar_Click(object sender, EventArgs e)
        {
            quitarProducto();
        }

        private void btnEditar_Click(object sender, EventArgs e)
        {
            editarProducto();
        }

        private void lvwListado_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!this.lvwListado.Focused) { return; }

            poblarProducto();
        }

        private void lvwListado_DoubleClick(object sender, EventArgs e)
        {
            publicaImagen();
        }

        private void btnCalcular_Click(object sender, EventArgs e)
        {
            calcularDsctototal();
        }

        private void txtDscto_TextChanged(object sender, EventArgs e)
        {
            //Se indica que ya se hizo el cálculo.
            this.bCalcDscto = false;
        }

        #endregion

        #region --- Metodo y Evento Scanner ---

        private void activarScanner(bool estado)
        {
            if (estado)
            {
                if (ParametrosAplicacion.scanner == null) { ParametrosAplicacion.scanner = new GS1.Scanner.Scan(this); }
                ParametrosAplicacion.scanner.EscanearDato += new GS1.Scanner.Scan.EscanearDatoEventHandler(scanner_EscanearDato);
                ParametrosAplicacion.scanner.ActivarScan();
            }
            else
            {
                if (ParametrosAplicacion.scanner != null)
                {
                    ParametrosAplicacion.scanner.EscanearDato -= new GS1.Scanner.Scan.EscanearDatoEventHandler(scanner_EscanearDato);
                    if (ParametrosAplicacion.scanner.IsActive) { ParametrosAplicacion.scanner.DesActivarScan(); }
                }
            }
        }

        private void scanner_EscanearDato(string pTipo, string pDato)
        {
            // Estableciendo codigo de barras leido
            this.codigoBarraActual = pDato;

            procesarCodigoBarra();
        }
        #endregion

        #region --- Metodos Propios ---
        private void cargarFormulario()
        {
            if (venta == null) { venta = new Venta(); }
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                this.WindowState = FormWindowState.Maximized;

                // Se instancia Listado de items a registrar
                this.listaItem = new ListaItem();

                // Se aplica estilo a listview
                Utilitario.aplicarEstiloGrilla(this.lvwListado, 
                                               this, 
                                               lvwListado_DoubleClick);

                // Activar Scanner
                activarScanner(true);

                // Cargar IGV
                this.igvActual = cargarIgv();

                //se crea una lista para la linea de ventas
                this.listaLineaVenta = new ListaLineaVenta();
            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void verImagen()
        {
            string codigoProducto = string.Empty;
            Producto producto = null;

            if (this.itemActual != null)
            {
                // Obteniendo codigo del producto a mostrar su imagen
                codigoProducto = this.itemActual.producto.codigo;
            }
            else
            {
                ListViewItem lineaActual = this.lvwListado.Items[this.lvwListado.SelectedIndices[0]];
                codigoProducto = lineaActual.Text;
            }
            //ojo

                try
                {
                    Cursor.Current = Cursors.WaitCursor;

                    
                    producto = obtenerProductoyComponentes(codigoProducto);

                    if (producto != null)
                    {
                        if (!producto.imagen.Equals(string.Empty))
                        {
                            using (frmProductoImagen frmProductoImagen = new frmProductoImagen())
                            {
                                frmProductoImagen.imagenProducto = producto.imagen.base64ToImage();
                                frmProductoImagen.ShowDialog();
                            }
                        }
                        else
                        {
                            Util.ShowMessageboxExclamacion("El producto seleccionado no tiene una imagen asignada.");
                        }
                    }
                    else
                    {
                        Util.ShowMessageboxExclamacion("No se encontro los datos del producto seleccionado.");
                    }
                }
                catch (Exception ex)
                {
                    Util.MensajeError(ex, this.Text);
                }
                finally
                {
                    Cursor.Current = Cursors.Default;
                }
            
        }

        private bool validarEntrada()
        {
            if ((this.listaLineaVenta == null) || (this.listaLineaVenta.lista.Count == 0))
            {
                Util.CampoNecesario(this.lvwListado, "Debe ingresar por lo menos un item", this.Text);
                return true;
            }

            return false;
        }

        private void guardar()
        {
            //Aca llama a la ventana para cerrar la venta y pone lista item en objeto venta

            if (validarEntrada()) { return; }
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                // se establece un cod en 0 para la venta no grabada
                venta.codVenta = Constantes.VALOR_CERO;

                venta.listaLineaVenta = this.listaLineaVenta;

                //-----------------------------------------------------------------------
                //El Precio ya incluye el IGV, en el momento que se decida si el cliente quiere factura o boleta se define el calculo.
                //-----------------------------------------------------------------------
                // Calculando el total a pagar
                venta.total = Math.Round(this.txtTotal.Text.ToDouble(),2);
                
                //obteniendo el monto total
                venta.subTotal = Math.Round((venta.total) / (1 + this.igvActual), 2);

                //calculando el IGV 
                venta.igv = Math.Round(venta.total - venta.subTotal,2);
                //-----------------------------------------------------------------------
               
                

                //Se levanta la pantalla de Venta para llenar los datos del cliente y los datos del documento de venta
                using (frmVenta frmVenta = new frmVenta())
                {
                    frmVenta.venta = venta;
                    if (frmVenta.ShowDialog() == DialogResult.Cancel) { frmVenta.Dispose(); return; }
                    frmVenta.Dispose();
                    salir();
                }
            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
            
        }

        private bool validarRepetidoItem(Item itembuscar)
        {
            bool resultado = false;

            foreach (Item item in this.listaItem.lista)
            {
                if (item.codItem.Equals(itembuscar.codItem))
                {
                    resultado = true;
                    break;
                }
            }

            return resultado;
        }

        private void procesarCodigoBarra()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_CONSULTAR_ITEM;

                operacion.item = new Item();
                operacion.item.codificacion = this.codigoBarraActual;

                // Instanciando y ejecutando llamada al ServicioREST
                using (ConexionREST conexionREST = new ConexionREST())
                {
                    contenidoXML = conexionREST.ejecutarOperacion(operacion);
                }

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Util.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                // Obtenido el Objeto Item
                this.itemActual = contenidoXML.DeserializarTo<Item>();

                if (this.itemActual != null)
                {
                    if (validarRepetidoItem(itemActual))
                    {
                        Util.ShowMessageboxExclamacion("El código de barra ya se encuentra agregado");
                        return;
                    }

                    if (!this.itemActual.estado.Equals(Constantes.ESTADO_ITEM_DISPONIBLE))
                    {
                        Util.ShowMessageboxExclamacion("Este item no se encuentra disponible");

                        // Limpiar los datos del item
                        limpiarDetalle();
                        return;
                    }

                    if (!this.itemActual.tienda.codigo.Equals(ParametrosAplicacion.TIENDA_ACTUAL.codigo))
                    {
                        Util.ShowMessageboxExclamacion("Este item no se encuentra registrada en esta tienda");

                        // Limpiar los datos del item
                        limpiarDetalle();
                        return;
                    }
                    //----------------------------------------------------------------------------
                    // Ingresando el Item a la lista
                    //----------------------------------------------------------------------------

                    Double Precio = 0;
                    this.txtDescripcion.Text = this.itemActual.producto.descripcion;
                    //----------------------------------------------------------------------------
                    //Calculando los montos con descuentos
                    if (Convert.ToDouble(this.txtDscto.Text) != 0)
                    {
                        //obteniendo el monto sin IGV
                        Double precioSinIgv = Math.Round((this.itemActual.producto.precioVentaMaximo) / (1 + this.igvActual), 2);

                        //Al precio sin impuestos se le quita el % de descuento
                        Double precioConDscto = Math.Round((precioSinIgv) / (1 +  (Convert.ToDouble(this.txtDscto.Text)/100)),2);
                                  
                        //Al precio con Dscto se le agrega el IGV
                        Precio = Math.Round(precioConDscto * (1 + this.igvActual),2);
                    }
                    else
                    {
                        Precio = this.itemActual.producto.precioVentaMaximo;
                    }
                    if (Precio < this.itemActual.producto.precioVentaMinimo)
                    {
                        this.txtPrecio.Text = this.itemActual.producto.precioVentaMinimo.ToString(Constantes.FORMATO_DECIMAL);
                    }
                    else
                    {
                        this.txtPrecio.Text = Precio.ToString(Constantes.FORMATO_DECIMAL);
                    }
                    //----------------------------------------------------------------------------
                    this.txtPrecioMin.Text = this.itemActual.producto.precioVentaMinimo.ToString(Constantes.FORMATO_DECIMAL);
                    this.txtPrecioMax.Text = this.itemActual.producto.precioVentaMaximo.ToString(Constantes.FORMATO_DECIMAL);

                    agregarItem();
                    //----------------------------------------------------------------------------
                }
                else
                {
                    // Limpiar los datos del item
                    limpiarDetalle();

                    Util.ShowMessageboxExclamacion("Código de barra inválido", this.Text);
                }

            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }

        }

        private void limpiarDetalle()
        {
            this.codigoBarraActual = string.Empty;

            // Limpiando los datos del item
            this.txtDescripcion.Text = string.Empty;
            this.txtPrecio.Text = Constantes.VALOR_CERO_DECIMAL;
            this.txtPrecioMax.Text = Constantes.VALOR_CERO_DECIMAL;
            this.txtPrecioMin.Text = Constantes.VALOR_CERO_DECIMAL;

            // Limpiar los datos item actual
            this.itemActual = null;
        }

        private bool validarAgregar()
        {
            this.txtDescripcion.Text = this.txtDescripcion.Text.Trim();
            this.txtPrecio.Text = this.txtPrecio.Text.Trim();

            if (this.txtDescripcion.Text.Equals(string.Empty))
            {
                Util.ShowMessageboxExclamacion("Debe seleccionar un producto para agregar", this.Text);
                return true;
            }

            if (this.txtPrecio.Text.Equals(string.Empty))
            {
                Util.CampoNecesario(this.txtPrecio, "Debe ingresar el precio del producto", this.Text);
                return true;
            }

            if ((this.txtPrecio.Text.EsEnteroConSigno()) &&
                (this.txtPrecio.Text.ToDouble() < this.itemActual.producto.precioVentaMinimo))
            {
                Util.CampoNecesario(this.txtPrecio, "Debe ingresar una precio válido", this.Text);
                return true;
            }

            return false;
        }

        private void editarProducto()
        {
             if (this.lvwListado.SelectedIndices.Count == 0) { return; }

             try
             {
                 Cursor.Current = Cursors.WaitCursor;
                 // Obteniendo producto de listview seleccionado
                 ListViewItem lineaActual = this.lvwListado.Items[this.lvwListado.SelectedIndices[0]];

                 Producto producto = new Producto();
                 String sCantidad = Constantes.VALOR_CERO;
                 String sPrecioTotal = Constantes.VALOR_CERO;
                 // Obteniendo LineaVenta seleccionada
                 foreach (LineaVenta lineaVentaSeleccionada in this.listaLineaVenta.lista)
                 {
                     if (lineaActual.Text.Equals(lineaVentaSeleccionada.producto.codigo))
                     {
                         //Asigna la variable para sumar el precio Total
                         double PrecioTotal = 0.0;
                         
                         //Barre con todos los items cambiando el precio Unitario a nivel de Item
                         foreach (LineaVentaItem lineaVentaItemSeleccionada in lineaVentaSeleccionada.listaLineaVentaItem.lista)
                         {
                             lineaVentaItemSeleccionada.item.precioVenta = Convert.ToDouble(this.txtPrecio.Text);
                             lineaVentaItemSeleccionada.item.producto.precioVentaTransaccion = Convert.ToDouble(this.txtPrecio.Text);

                             PrecioTotal = PrecioTotal + lineaVentaItemSeleccionada.item.precioVenta;   
                             
                         }
                         //Con el nuevo Precio total se cambia en la lista
                         lineaVentaSeleccionada.precio = PrecioTotal;
                         //Con el precio unitario de la transaccion
                         lineaVentaSeleccionada.producto.precioVentaTransaccion = Convert.ToDouble(this.txtPrecio.Text);
                         
                         producto.codigo = lineaVentaSeleccionada.producto.codigo;
                         producto.codProductoProveedor = lineaVentaSeleccionada.producto.codProductoProveedor;
                         producto.descripcion = lineaVentaSeleccionada.producto.descripcion;
                         sCantidad = lineaVentaSeleccionada.cantidad;
                         sPrecioTotal = PrecioTotal.ToString(Constantes.FORMATO_DECIMAL);
                         //Sale del foreach por que ya había encontrado el producto
                         break;
                     }
                 }

                 // Se modifica la linea del producto en la grilla
                 this.lvwListado.BeginUpdate();

                 this.lvwListado.Items.Remove(lineaActual);

                 // Creando nuevaLinea para listview
                 ListViewItem nuevaLinea = new ListViewItem(producto.codigo);
                 nuevaLinea.SubItems.Add(producto.codProductoProveedor);
                 nuevaLinea.SubItems.Add(producto.descripcion);
                 nuevaLinea.SubItems.Add(sCantidad);
                 nuevaLinea.SubItems.Add(sPrecioTotal);

                 // Agregando nuevaLinea a listview
                 this.lvwListado.Items.Add(nuevaLinea);

                 // Actualizando grilla
                 this.lvwListado.EndUpdate();


                 //Calcula el total nuevamente con el nuevo precio
                 calcularTotal();

                 //habilita nuevamente el listado
                 this.lvwListado.Enabled = true;

                 limpiarDetalle();

                 //Activa el Scanner
                 activarScanner(true);
             }
             catch (Exception ex)
             {
                 Util.MensajeError(ex, this.Text);
             }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
          
        }

        private void quitarProducto()
        {
            if (this.lvwListado.SelectedIndices.Count == 0) { return; }

            if (!Util.ShowMessageboxPregunta("¿Esta seguro de eliminar el producto de la lista seleccionada?", this.Text)) { return; }

            try
            {
                Cursor.Current = Cursors.WaitCursor;
                // Obteniendo item de listview seleccionado
                ListViewItem lineaActual = this.lvwListado.Items[this.lvwListado.SelectedIndices[0]];

                LineaVenta lineaVentaSeleccionada = null;

                // Obteniendo LineaVenta seleccionada
                foreach (LineaVenta lineaVenta in this.listaLineaVenta.lista)
                {
                    if (lineaActual.Text.Equals(lineaVenta.producto.codigo))
                    {
                        lineaVentaSeleccionada = lineaVenta;
                    }
                }
                // Eliminando item del grilla
                this.lvwListado.Items.Remove(lineaActual);

                foreach (LineaVentaItem lineaVentaItemRetirar in lineaVentaSeleccionada.listaLineaVentaItem.lista)
                {
                    //Quitando los items de la listaitem
                    this.listaItem.remove(lineaVentaItemRetirar.item);
                }

                // Quitando elemento del listado
                this.listaLineaVenta.remove(lineaVentaSeleccionada);


            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }

            // Recalcular total
            calcularTotal();

            this.lvwListado.Enabled = true;

            limpiarDetalle();

            activarScanner(true);

        }

        private void agregarItem()
        {
            try
            {
                if (validarAgregar()) { return; }

                // Instanciando item a agregar
                Item itemAgregar = new Item();

                itemAgregar.codItem = this.itemActual.codItem;
                itemAgregar.codificacion = this.itemActual.codificacion;

                // Estableciendo producto del item
                itemAgregar.producto = new Producto();
                itemAgregar.producto.codigo = this.itemActual.producto.codigo;
                itemAgregar.producto.codProductoProveedor = this.itemActual.producto.codProductoProveedor;
                itemAgregar.producto.descripcion = this.itemActual.producto.descripcion;
                itemAgregar.producto.precioVentaMaximo = this.itemActual.producto.precioVentaMaximo;
                itemAgregar.producto.precioVentaMinimo = this.itemActual.producto.precioVentaMinimo;

                // Establecer el precio de venta
                itemAgregar.producto.precioVentaTransaccion = Convert.ToDouble(this.txtPrecio.Text);

                // Establecer el precio de venta(SOLO para mostrar en la grilla)
                itemAgregar.precioVenta = Convert.ToDouble(this.txtPrecio.Text);

                // Establecer el estado vendido del item
                itemAgregar.estado = Constantes.ESTADO_ITEM_VENDIDO;

                Boolean bProductoNuevo = true;
                int iContarLineas = 1;
                String sCantidad = Constantes.VALOR_CERO;
                String sPrecioVentaTotal = Constantes.VALOR_CERO;

                foreach (LineaVenta lineaVenta in this.listaLineaVenta.lista)
                {
                    if (itemAgregar.producto.codigo.Equals(lineaVenta.producto.codigo))
                    {
                        bProductoNuevo = false;
                        //Se actualiza la cantidad de productos que se están vendiendo
                        lineaVenta.cantidad = (Convert.ToInt32(lineaVenta.cantidad) + 1).ToString();
                        sCantidad = lineaVenta.cantidad;

                        //En el precio de la linea de Venta se pondrá el precio total
                        lineaVenta.precio = Convert.ToDouble(this.txtPrecio.Text) * Convert.ToInt32(lineaVenta.cantidad);
                        //En el precio del producto en Linea de Venta se pondrá el precio unitario para mayor facilidad
                        lineaVenta.producto.precioVentaTransaccion = Convert.ToDouble(this.txtPrecio.Text);
                        sPrecioVentaTotal = lineaVenta.precio.ToString(Constantes.FORMATO_DECIMAL);

                        foreach (LineaVentaItem lineaVentaItemCargado in lineaVenta.listaLineaVentaItem.lista)
                        {
                            //En la Venta Item y en el Item se pondrá el precio ultimo asignado de manera unitaria
                            lineaVentaItemCargado.item.producto.precioVentaTransaccion = Convert.ToDouble(this.txtPrecio.Text);
                            lineaVentaItemCargado.item.precioVenta = Convert.ToDouble(this.txtPrecio.Text);
                        }

                        LineaVentaItem lineaVentaItemNuevo = new LineaVentaItem();
                        lineaVentaItemNuevo.item = itemAgregar;
                        lineaVentaItemNuevo.codVenta = Constantes.VALOR_CERO;
                        lineaVentaItemNuevo.numeroLinea = lineaVenta.numeroLinea;

                        lineaVenta.listaLineaVentaItem.add(lineaVentaItemNuevo);

                        // Se modifica la linea del producto en la grilla
                        this.lvwListado.BeginUpdate();

                        // Se recupera la linea en el ListTreeView
                        foreach (ListViewItem lineaActual in this.lvwListado.Items)
                        {
                            if (lineaActual.Text.Equals(itemAgregar.producto.codigo))
                            {
                                // Eliminando el producto de la grilla
                                this.lvwListado.Items.Remove(lineaActual);
                                break;
                            }
                        }

                        // Actualizando grilla
                        this.lvwListado.EndUpdate();

                    }
                    iContarLineas++;
                }

                if (bProductoNuevo)
                {
                    LineaVenta lineaVentaNuevo = new LineaVenta();

                    //El código de Venta aún no está asignado
                    lineaVentaNuevo.codVenta = Constantes.VALOR_CERO;

                    //Se asigna el producto a la linea de la venta nueva
                    lineaVentaNuevo.producto = itemAgregar.producto;

                    //Como es un producto nuevo se pone como cantidad 1
                    lineaVentaNuevo.cantidad = Constantes.VALOR_UNO;
                    sCantidad = lineaVentaNuevo.cantidad;

                    //Se asigna como número de linea a la linea Siguiente en la lista
                    lineaVentaNuevo.numeroLinea = iContarLineas.ToString();

                    //En el precio de la linea de Venta y del producto en Linea de Venta se pondrá el precio total
                    lineaVentaNuevo.precio = Convert.ToDouble(this.txtPrecio.Text);
                    lineaVentaNuevo.producto.precioVentaTransaccion = Convert.ToDouble(this.txtPrecio.Text);
                    sPrecioVentaTotal = lineaVentaNuevo.precio.ToString(Constantes.FORMATO_DECIMAL);
                    
                    LineaVentaItem lineaVentaItemNuevo = new LineaVentaItem();
                    lineaVentaItemNuevo.codVenta = Constantes.VALOR_CERO;
                    lineaVentaItemNuevo.numeroLinea = lineaVentaNuevo.numeroLinea;
                    //En el precio del item se mantiene el precio unitario
                    lineaVentaItemNuevo.item = itemAgregar;

                    ListaLineaVentaItem listaLineaVentaItem = new ListaLineaVentaItem();
                    listaLineaVentaItem.add(lineaVentaItemNuevo);

                    lineaVentaNuevo.listaLineaVentaItem = listaLineaVentaItem;

                    this.listaLineaVenta.add(lineaVentaNuevo);

                }
                
                //Solo se agrega para facilitar que no se lea dos veces el mismo código, esta lista solo se usará para validaciones
                this.listaItem.add(itemAgregar);

                // Se agrega producto a la grilla
                this.lvwListado.BeginUpdate();

                // Creando nuevaLinea para listview
                ListViewItem nuevaLinea = new ListViewItem(itemAgregar.producto.codigo);
                nuevaLinea.SubItems.Add(itemAgregar.producto.codProductoProveedor);
                nuevaLinea.SubItems.Add(itemAgregar.producto.descripcion);
                nuevaLinea.SubItems.Add(sCantidad);
                nuevaLinea.SubItems.Add(sPrecioVentaTotal);

                // Agregando nuevaLinea a listview
                this.lvwListado.Items.Add(nuevaLinea);

                // Actualizando grilla
                this.lvwListado.EndUpdate();

                // Limpiando controles
                limpiarDetalle();

                // Recalcular total
                calcularTotal();
            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void poblarProducto()
        {
            if (this.lvwListado.SelectedIndices.Count == 0) { return; }

            try
            {
                Cursor.Current = Cursors.WaitCursor;
                // Obteniendo producto de listview seleccionado
                ListViewItem lineaActual = this.lvwListado.Items[this.lvwListado.SelectedIndices[0]];

                // Obteniendo LineaVenta seleccionada
                foreach (LineaVenta lineaVentaSeleccionada in this.listaLineaVenta.lista)
                {
                    if (lineaActual.Text.Equals(lineaVentaSeleccionada.producto.codigo))
                    {
                        this.txtDescripcion.Text = lineaVentaSeleccionada.producto.descripcion;
                        this.txtPrecio.Text = lineaVentaSeleccionada.producto.precioVentaTransaccion.ToString(Constantes.FORMATO_DECIMAL);

                        this.txtPrecioMin.Text = lineaVentaSeleccionada.producto.precioVentaMinimo.ToString(Constantes.FORMATO_DECIMAL);
                        this.txtPrecioMax.Text = lineaVentaSeleccionada.producto.precioVentaMaximo.ToString(Constantes.FORMATO_DECIMAL);

                        this.lvwListado.Enabled = false;
                        activarScanner(false);
                        //Salir del foreach por que ya se encontró la linea que se buscaba editar
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void calcularDsctototal()
        {
            if (this.listaLineaVenta != null)
            {

                //Se pone una variable de llave para evitar que se vuelva a calcular.
                if (!bCalcDscto && Convert.ToDouble(this.txtDscto.Text) >= 0)
                {
                    //Se barre sobre los precios de Venta máximo de cada uno de los items se vuelve a cargar el precio con descuento
                    this.lvwListado.Items.Clear();

                    foreach (LineaVenta lineaVentaCalculo in this.listaLineaVenta.lista)
                    {
                        //Primero se calcula a nivel unitario
                        Double PrecioTotal = 0.0;
                        Double PrecioUnitarioTransaccion = 0.0;
                        //----------------------------------------------------------------------------
                        //Calculando los montos con descuentos
                        //obteniendo el monto sin IGV

                        Double precioSinIgv = Math.Round((lineaVentaCalculo.producto.precioVentaMaximo) / (1 + this.igvActual), 2);

                        //Al precio sin impuestos se le quita el % de descuento

                        Double precioConDscto = Math.Round((precioSinIgv) / (1 + (Convert.ToDouble(this.txtDscto.Text) / 100)), 2);

                        //Al precio con Dscto se le agrega el IGV

                        Double Precio = Math.Round(precioConDscto * (1 + this.igvActual), 2);

                        //----------------------------------------------------------------------------

                        foreach (LineaVentaItem lineaVentaItemCalculoUnitario in lineaVentaCalculo.listaLineaVentaItem.lista)
                        {
                            if (Precio < lineaVentaItemCalculoUnitario.item.producto.precioVentaMinimo)
                            {
                                lineaVentaItemCalculoUnitario.item.producto.precioVentaTransaccion = lineaVentaCalculo.producto.precioVentaMinimo;
                                lineaVentaItemCalculoUnitario.item.precioVenta = lineaVentaCalculo.producto.precioVentaMinimo;
                            }
                            else
                            {
                                lineaVentaItemCalculoUnitario.item.producto.precioVentaTransaccion = Precio;
                                lineaVentaItemCalculoUnitario.item.precioVenta = Precio;
                            }
                            //Calcula el precio total Acumulado por cada una de las lineas
                            PrecioTotal = PrecioTotal + lineaVentaItemCalculoUnitario.item.producto.precioVentaTransaccion;
                            PrecioUnitarioTransaccion = lineaVentaItemCalculoUnitario.item.producto.precioVentaTransaccion;
                        }
                        //Segundo se calcula a nivel consolidado
                        //----------------------------------------------------------------------------
                        //Precio Unitario por linea
                        lineaVentaCalculo.producto.precioVentaTransaccion = PrecioUnitarioTransaccion;
                        //Precio Total por linea
                        lineaVentaCalculo.precio = PrecioTotal;
                        //----------------------------------------------------------------------------

                        // Se agrega producto a la grilla
                        this.lvwListado.BeginUpdate();

                        // Creando nuevaLinea para listview
                        ListViewItem nuevaLinea = new ListViewItem(lineaVentaCalculo.producto.codigo);
                        nuevaLinea.SubItems.Add(lineaVentaCalculo.producto.codProductoProveedor);
                        nuevaLinea.SubItems.Add(lineaVentaCalculo.producto.descripcion);
                        nuevaLinea.SubItems.Add(lineaVentaCalculo.cantidad);
                        nuevaLinea.SubItems.Add(PrecioTotal.ToString(Constantes.FORMATO_DECIMAL));

                        // Agregando nuevaLinea a listview
                        this.lvwListado.Items.Add(nuevaLinea);

                        // Actualizando grilla
                        this.lvwListado.EndUpdate();

                    }
                    //Se indica que ya se hizo el cálculo.
                    this.bCalcDscto = true;

                //Realiza un cáculo total
                    calcularTotal();
                }
            }
        }

        private void calcularTotal()
        {
            // Obteniendo el monto total
            double total = 0.0;

            foreach (LineaVenta lineaVenta in this.listaLineaVenta.lista)
            {
                total = total + lineaVenta.precio;
            }

            // Mostrando el monto total
            this.txtTotal.Text = total.ToString(Constantes.FORMATO_DECIMAL);
        }

        private void salir()
        {
            this.Close();
        }

        private void publicaImagen()
        {
            if (!this.lvwListado.Focused) { return; }
            string codigoProducto = string.Empty;
            Producto producto = null;

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                // Obteniendo codigo del producto a mostrar su imagen
                codigoProducto = this.lvwListado.Items[this.lvwListado.SelectedIndices[0]].Text;

                producto = obtenerProductoyComponentes(codigoProducto);

                if (producto != null)
                {
                    if (!producto.imagen.Equals(string.Empty))
                    {
                        using (frmProductoImagen frmProductoImagen = new frmProductoImagen())
                        {
                            frmProductoImagen.imagenProducto = producto.imagen.base64ToImage();
                            frmProductoImagen.ShowDialog();
                            frmProductoImagen.Dispose();
                        }
                    }
                    else
                    {
                        Util.ShowMessageboxExclamacion("El producto seleccionado no tiene una imagen asignada.");
                    }
                }
                else
                {
                    Util.ShowMessageboxExclamacion("No se encontro los datos del producto seleccionado.");
                }
            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }

        }

        private Item obtenerItem(string codigoitem)
        {
            Item item = null;
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_OBTENER_ITEM;
            operacion.item = new Item { codItem = codigoitem };

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Util.ShowMessageboxError(operacionError.descripcion);
                return null;
            }

            // Obteniendo Objeto de Producto
            item = contenidoXML.DeserializarTo<Item>();

            return item;

        }

        private Producto obtenerProductoyComponentes(string codigoProducto)
        {
            Producto producto = null;
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_OBTENER_PRODUCTO;
            operacion.producto = new Producto { codigo = codigoProducto };

            operacion.tienda = new Tienda();
            operacion.tienda = ParametrosAplicacion.TIENDA_ACTUAL;

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Util.ShowMessageboxError(operacionError.descripcion);
                return null;
            }

            // Obteniendo Objeto de Producto
            producto = contenidoXML.DeserializarTo<Producto>();

            return producto;
        }

        private Double cargarIgv()
        {
            Double igv = 0;
            Operacion operacion = null;
            ListaParametro listaParametro = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_LISTAR_PARAMETROS;

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Util.ShowMessageboxError(operacionError.descripcion);
                return 0;
            }

            // Obteniendo Objeto de Nivel
            listaParametro = contenidoXML.DeserializarTo<ListaParametro>();

            foreach (Parametro parametro in listaParametro.lista)
            {
                switch (parametro.codigo)
                {
                    case Constantes.CODIGO_PARAMETRO_IGV:
                        igv = parametro.valor.ToDouble();
                        break;
                }
            }
            return igv;
        }

        #endregion





    }
}